// Project name:JavaRedis
// Creator:muhong
// Date time:2022/12/8,10:13 下午
// Name:NioSocketChannel

package org.gmh.channel.nio;

import org.gmh.channel.Channel;
import org.gmh.channel.ChannelFuture;
import org.gmh.channel.ChannelPromise;
import org.gmh.channel.EventLoop;
import org.gmh.channel.handler.ChannelPipeline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel;

public class NioSocketChannel extends AbstractNioByteChannel {

    private final static Logger logger = LoggerFactory.getLogger(NioSocketChannel.class);

    protected NioSocketChannel(Channel parent, SelectableChannel ch) {
        super(parent, ch);
    }

    @Override
    protected int doReadBytes(ByteBuffer byteBuffer) throws Exception {
        // 调用java channel来读数据
        logger.info("do read some byte from channel");
        SocketChannel channel = (SocketChannel) javaChannel();
        try {
            return channel.read(byteBuffer);
        } catch (ClosedChannelException ignore) {
            return -1;
        }
    }

    @Override
    public boolean isRegistered() {
        return false;
    }

    @Override
    public NioUnsafe unsafe() {
        return (NioUnsafe) super.unsafe();
    }

    @Override
    public ChannelPipeline pipeline() {
        return super.pipeline();
    }

    @Override
    public SocketChannel javaChannel() {
        return (SocketChannel) super.javaChannel();
    }

    @Override
    public boolean isActive() {
        SocketChannel ch = javaChannel();
        return ch.isOpen() && ch.isRegistered();
    }

    @Override
    protected void doClose() throws Exception {
        super.doClose();
        javaChannel().close();
    }

    @Override
    protected ChannelFuture shutdownInput() {
        ChannelPromise promise = newPromise();
        EventLoop loop = eventLoop();
        if (loop.inEventLoop()) {
            shutdownInput0(promise);
        } else {
            loop.execute(new Runnable() {
                @Override
                public void run() {
                    shutdownInput0(promise);
                }
            });
        }
        return promise;
    }

    private void shutdownInput0(final ChannelPromise promise) {
        try {
            javaChannel().shutdownInput();
        } catch (Throwable t) {
            promise.setFailure(t);
        }
    }

    @Override
    public ChannelFuture write(Object msg) {
        return null;
    }

    @Override
    public ChannelFuture close() {
        return null;
    }

    private final class NioSocketChannelUnsafe extends NioByteUnsafe {


    }
}
